<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>文本相似度检测</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script>
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    <style>
        body {
            background-color: #1a1a1a;
            color: #ffffff;
            font-family: 'Arial', sans-serif;
            margin: 0;
            padding: 10px;
            min-height: 100vh;
            background: linear-gradient(135deg, #1a1a1a 0%, #2d2d2d 100%);
        }

        .container {
            max-width: 900px;
            width: 95%;
            margin: 0 auto;
            padding: clamp(20px, 4vw, 40px);
            background-color: rgba(45, 45, 45, 0.9);
            border-radius: clamp(12px, 2vw, 20px);
            box-shadow: 0 0 30px rgba(0, 255, 136, 0.1);
            border: 1px solid rgba(0, 255, 136, 0.1);
            backdrop-filter: blur(10px);
            position: relative;
            z-index: 1;
        }

        .text-box {
            margin-bottom: clamp(20px, 4vw, 40px);
            padding: clamp(15px, 3vw, 25px);
            background-color: rgba(61, 61, 61, 0.6);
            border-radius: 15px;
            border: 1px solid rgba(0, 204, 255, 0.1);
            transition: all 0.3s ease;
        }

        .text-box:hover {
            border-color: rgba(0, 204, 255, 0.3);
            box-shadow: 0 0 15px rgba(0, 204, 255, 0.1);
        }

        h1 {
            text-align: center;
            color: #00ff88;
            margin-bottom: clamp(30px, 5vw, 50px);
            text-shadow: 0 0 20px rgba(0, 255, 136, 0.3);
            font-size: clamp(1.8em, 4vw, 2.5em);
        }

        h3 {
            color: #00ccff;
            margin: 0 0 15px 0;
            font-size: 1.3em;
            text-shadow: 0 0 10px rgba(0, 204, 255, 0.3);
        }

        textarea {
            width: calc(100% - clamp(20px, 4vw, 30px));
            height: clamp(100px, 20vh, 150px);
            margin: 15px 0;
            padding: 15px;
            background-color: rgba(30, 30, 30, 0.9);
            border: 2px solid rgba(77, 77, 77, 0.5);
            border-radius: 12px;
            color: #ffffff;
            font-size: clamp(14px, 2vw, 16px);
            resize: vertical;
            transition: all 0.3s ease;
            box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.2);
            min-height: 120px;
            max-height: 300px;
        }

        textarea:focus {
            outline: none;
            border-color: #00ff88;
            box-shadow: 0 0 15px rgba(0, 255, 136, 0.2),
                       inset 0 0 10px rgba(0, 255, 136, 0.1);
        }

        button {
            display: block;
            width: clamp(180px, 30vw, 220px);
            margin: 40px auto;
            padding: clamp(12px, 2vw, 18px) clamp(20px, 4vw, 35px);
            background: linear-gradient(45deg, #00ccff, #00ff88);
            color: white;
            border: none;
            border-radius: 30px;
            font-size: clamp(14px, 2vw, 18px);
            font-weight: bold;
            cursor: pointer;
            transition: all 0.3s ease;
            position: relative;
            overflow: hidden;
            box-shadow: 0 5px 15px rgba(0, 255, 136, 0.2);
        }

        button:hover {
            transform: translateY(-3px);
            box-shadow: 0 8px 25px rgba(0, 255, 136, 0.4);
        }

        button:active {
            transform: translateY(1px);
        }

        button::after {
            content: '';
            position: absolute;
            top: -50%;
            left: -50%;
            width: 200%;
            height: 200%;
            background: linear-gradient(
                45deg,
                transparent,
                rgba(255, 255, 255, 0.1),
                transparent
            );
            transform: rotate(45deg);
            transition: all 0.5s ease;
        }

        button:hover::after {
            transform: rotate(45deg) translate(50%, 50%);
        }

        .result {
            margin-top: 30px;
            text-align: center;
            padding: 25px;
            background-color: rgba(61, 61, 61, 0.6);
            border-radius: 15px;
            animation: fadeIn 0.5s ease;
            border: 1px solid rgba(0, 255, 136, 0.2);
            box-shadow: 0 0 20px rgba(0, 255, 136, 0.1);
        }

        .similarity-label {
            font-size: 18px;
            color: #00ccff;
            margin-bottom: 10px;
            text-transform: uppercase;
            letter-spacing: 2px;
        }

        .similarity-value {
            font-size: 36px;
            color: #00ff88;
            font-weight: bold;
            text-shadow: 0 0 15px rgba(0, 255, 136, 0.3);
        }

        @keyframes fadeIn {
            from {
                opacity: 0;
                transform: translateY(20px);
            }
            to {
                opacity: 1;
                transform: translateY(0);
            }
        }

        .loading {
            position: relative;
            pointer-events: none;
        }

        .loading::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: linear-gradient(45deg, #00ccff, #00ff88);
            opacity: 0.3;
            border-radius: 30px;
            animation: pulse 1.5s infinite;
        }

        @keyframes pulse {
            0% {
                opacity: 0.3;
            }
            50% {
                opacity: 0.5;
            }
            100% {
                opacity: 0.3;
            }
        }

        .loading::after {
            content: '处理中...';
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            color: white;
            text-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
        }

        /* 添加历史记录相关样式 */
        .history {
            margin-top: 40px;
            padding: 20px;
            background-color: rgba(61, 61, 61, 0.6);
            border-radius: 15px;
            border: 1px solid rgba(0, 204, 255, 0.1);
        }

        .history h2 {
            color: #00ccff;
            margin-bottom: 20px;
            text-align: center;
            font-size: 1.8em;
            text-shadow: 0 0 10px rgba(0, 204, 255, 0.3);
        }

        .history-item {
            position: relative;
            padding: 20px;
            padding-top: 50px;
            margin-bottom: 20px;
            background-color: rgba(30, 30, 30, 0.8);
            border-radius: 12px;
            border: 1px solid rgba(0, 255, 136, 0.1);
            transition: all 0.3s ease;
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
        }

        .history-item:hover {
            border-color: rgba(0, 255, 136, 0.3);
            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3);
            transform: translateY(-2px);
        }

        .delete-item {
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            height: 36px;
            width: 100%;
            border-radius: 12px 12px 0 0;
            background: rgba(25, 25, 25, 0.95);
            border: none;
            border-bottom: 1px solid rgba(255, 255, 255, 0.05);
            color: #444;
            font-size: 14px;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            opacity: 0;
            transition: all 0.3s ease;
            backdrop-filter: blur(4px);
            padding: 0;
            line-height: 1;
        }

        .history-item:hover .delete-item {
            opacity: 1;
        }

        .delete-item:hover {
            background: rgba(35, 35, 35, 0.95);
            color: #666;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
        }

        .delete-item::before {
            content: '删除此记录';
            position: static;
            transform: none;
            padding: 0;
            border: none;
            font-size: 13px;
            opacity: 1;
            pointer-events: none;
        }

        .delete-item:hover::before {
            color: #ff4444;
        }

        .history-texts {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
            gap: clamp(10px, 2vw, 20px);
            padding-right: clamp(20px, 4vw, 40px);
            margin-bottom: 15px;
        }

        .history-text {
            margin: 0;
            padding: clamp(10px, 2vw, 15px);
            background-color: rgba(40, 40, 40, 0.6);
            border-radius: 8px;
            font-size: clamp(12px, 1.5vw, 14px);
            border: 1px solid rgba(255, 255, 255, 0.05);
            line-height: 1.4;
        }

        .history-result {
            text-align: center;
            color: #00ff88;
            font-size: clamp(14px, 2vw, 16px);
            font-weight: bold;
            margin: 15px 0;
            padding: 10px;
            background-color: rgba(0, 255, 136, 0.1);
            border-radius: 6px;
        }

        .history-time {
            text-align: right;
            color: #666;
            font-size: clamp(10px, 1.5vw, 12px);
            margin-top: 10px;
            font-style: italic;
        }

        .clear-history {
            display: block;
            width: auto;
            min-width: 160px;
            margin: 30px auto 0;
            padding: 12px 25px;
            background: rgba(40, 40, 40, 0.95);
            color: #666;
            border: 1px solid rgba(255, 255, 255, 0.1);
            border-radius: 8px;
            font-size: 14px;
            cursor: pointer;
            transition: all 0.3s ease;
        }

        .clear-history:hover {
            transform: translateY(-2px);
            background: rgba(50, 50, 50, 0.95);
            color: #ff4444;
            border-color: rgba(255, 68, 68, 0.3);
            box-shadow: 0 4px 15px rgba(255, 68, 68, 0.2);
        }

        /* 移动设备适配 */
        @media (max-width: 768px) {
            .container {
                width: 100%;
                padding: 15px;
            }

            .text-box {
                padding: 15px;
            }

            .history-texts {
                grid-template-columns: 1fr;
                padding-right: 0;
            }

            .delete-item {
                opacity: 1;
            }

            .clear-history {
                width: 100%;
                margin: 20px 0;
            }
        }

        /* 平板设备适配 */
        @media (min-width: 769px) and (max-width: 1024px) {
            .container {
                width: 90%;
            }

            .history-texts {
                grid-template-columns: repeat(2, 1fr);
            }
        }

        /* 确保在大屏幕上的最大宽度 */
        @media (min-width: 1025px) {
            .container {
                max-width: 900px;
            }
        }

        .bubbles {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            overflow: hidden;
            z-index: 0;
            pointer-events: none;
        }

        .bubble {
            position: absolute;
            bottom: -100px;
            width: 160px;
            height: 160px;
            background: linear-gradient(45deg, 
                rgba(0, 255, 136, 0.15),
                rgba(0, 204, 255, 0.2)
            );
            border-radius: 50%;
            animation: rise 20s infinite ease-in;
            opacity: 0;
            transition: all 0.3s ease;
            pointer-events: auto;
            z-index: 0;
        }

        .bubble:nth-child(1) {
            left: 10%;
            width: 240px;
            height: 240px;
            animation-duration: 18s;
        }

        .bubble:nth-child(2) {
            left: 20%;
            width: 180px;
            height: 180px;
            animation-duration: 22s;
        }

        .bubble:nth-child(3) {
            left: 35%;
            width: 280px;
            height: 280px;
            animation-duration: 20s;
        }

        .bubble:nth-child(4) {
            left: 50%;
            width: 200px;
            height: 200px;
            animation-duration: 24s;
        }

        .bubble:nth-child(5) {
            left: 65%;
            width: 220px;
            height: 220px;
            animation-duration: 21s;
        }

        .bubble:nth-child(6) {
            left: 80%;
            width: 260px;
            height: 260px;
            animation-duration: 19s;
        }

        .bubble:nth-child(7) {
            left: 90%;
            width: 170px;
            height: 170px;
            animation-duration: 23s;
        }

        .bubble:nth-child(8) {
            left: 25%;
            width: 190px;
            height: 190px;
            animation-duration: 20s;
        }

        .bubble:nth-child(9) {
            left: 45%;
            width: 250px;
            height: 250px;
            animation-duration: 22s;
        }

        .bubble:nth-child(10) {
            left: 70%;
            width: 210px;
            height: 210px;
            animation-duration: 21s;
        }

        .bubble:hover {
            transform: scale(1.2);
            background: linear-gradient(45deg,
                rgba(255, 82, 182, 0.2),
                rgba(255, 123, 0, 0.25)
            );
            box-shadow: 0 0 30px rgba(255, 82, 182, 0.3);
            z-index: -1;
        }

        @keyframes rise {
            0% {
                bottom: -100px;
                transform: translateX(0) scale(1) rotate(0deg);
                opacity: 0;
            }
            10% {
                opacity: 0.5;
            }
            50% {
                transform: translateX(100px) scale(1.2) rotate(180deg);
                opacity: 0.7;
            }
            90% {
                opacity: 0.5;
            }
            100% {
                bottom: 120vh;
                transform: translateX(-100px) scale(0.8) rotate(360deg);
                opacity: 0;
            }
        }

        .bubble.follow {
            transition: transform 0.8s cubic-bezier(0.4, 0, 0.2, 1);
        }

        /* 添加消失动画 */
        @keyframes popOut {
            0% {
                transform: scale(1);
                opacity: 1;
            }
            100% {
                transform: scale(1.5);
                opacity: 0;
            }
        }

        .bubble.pop {
            animation: popOut 0.3s ease forwards;
            pointer-events: none;
        }

        /* 更扭曲的椭圆形气泡 */
        .bubble:nth-child(3n) {
            border-radius: 70% 30% 50% 50% / 30% 70% 30% 70%;
            animation: rise 22s infinite ease-in-out;
            transform-origin: center;
        }

        /* 更扭曲的不规则形状气泡 */
        .bubble:nth-child(3n+1) {
            border-radius: 20% 80% 20% 80% / 80% 20% 80% 20%;
            animation: rise 25s infinite ease-in-out;
        }

        /* 更扭曲的水滴形状气泡 */
        .bubble:nth-child(3n+2) {
            border-radius: 80% 20% 60% 40% / 40% 60% 40% 60%;
            animation: rise 23s infinite ease-in-out;
        }

        /* 修改动画中的形状变化 */
        @keyframes rise {
            0% {
                bottom: -100px;
                transform: translateX(0) scale(1) rotate(0deg);
                border-radius: 50%;
                opacity: 0;
            }
            20% {
                border-radius: 70% 30% 50% 50% / 30% 70% 30% 70%;
                opacity: 0.5;
            }
            40% {
                border-radius: 20% 80% 20% 80% / 80% 20% 80% 20%;
            }
            60% {
                transform: translateX(100px) scale(1.2) rotate(180deg);
                border-radius: 80% 20% 60% 40% / 40% 60% 40% 60%;
                opacity: 0.7;
            }
            80% {
                border-radius: 40% 60% 20% 80% / 80% 20% 60% 40%;
                opacity: 0.5;
            }
            100% {
                bottom: 120vh;
                transform: translateX(-100px) scale(0.8) rotate(360deg);
                border-radius: 50%;
                opacity: 0;
            }
        }

        /* 修改随机形状数组 */
        <script>
            // ... 其他代码保持不变 ...
            
            // 在 createNewBubble 函数中更新形状数组
            const shapes = [
                '50%',  // 圆形
                '70% 30% 50% 50% / 30% 70% 30% 70%',  // 极度扭曲的椭圆
                '20% 80% 20% 80% / 80% 20% 80% 20%',  // 极度扭曲的不规则形状
                '80% 20% 60% 40% / 40% 60% 40% 60%',  // 扭曲的水滴
                '90% 10% 70% 30% / 30% 70% 30% 70%',  // 更极端的扭曲
                '25% 75% 25% 75% / 75% 25% 75% 25%',  // 星形变体
                '85% 15% 50% 50% / 50% 50% 15% 85%',  // 不对称扭曲
                '10% 90% 30% 70% / 70% 30% 90% 10%'   // 极端不对称
            ];
        </script>
    </style>
</head>
<body>
    <div class="bubbles">
        <div class="bubble"></div>
        <div class="bubble"></div>
        <div class="bubble"></div>
        <div class="bubble"></div>
        <div class="bubble"></div>
        <div class="bubble"></div>
        <div class="bubble"></div>
        <div class="bubble"></div>
        <div class="bubble"></div>
        <div class="bubble"></div>
    </div>
    
    <div id="app" class="container">
        <h1>文本相似度检测</h1>
        <div class="text-box">
            <h3>文本1：</h3>
            <textarea v-model="text1" placeholder="请输入第一段文本..."></textarea>
        </div>
        <div class="text-box">
            <h3>文本2：</h3>
            <textarea v-model="text2" placeholder="请输入第二段文本..."></textarea>
        </div>
        <button @click="compareTexts" :class="{ loading: isLoading }">
            比较相似度
        </button>
        <div class="result" v-if="similarity !== null">
            <div class="similarity-label">相似度</div>
            <div class="similarity-value">{{ (similarity * 100).toFixed(2) }}%</div>
        </div>
        
        <!-- 添加历史记录部分 -->
        <div class="history" v-if="history.length > 0">
            <h2>历史记录</h2>
            <div class="history-item" v-for="(item, index) in history" :key="index">
                <button class="delete-item" @click.stop="deleteHistoryItem(index)" title="删除这条记录">×</button>
                <div class="history-texts">
                    <div class="history-text">{{ item.text1 }}</div>
                    <div class="history-text">{{ item.text2 }}</div>
                </div>
                <div class="history-result">
                    相似度：{{ (item.similarity * 100).toFixed(2) }}%
                </div>
                <div class="history-time">{{ item.time }}</div>
            </div>
            <button class="clear-history" @click="clearHistory">清除全部历史记录</button>
        </div>
    </div>

    <script>
        new Vue({
            el: '#app',
            data: {
                text1: '',
                text2: '',
                similarity: null,
                baseUrl: 'http://10.0.105.90:9090',
                isLoading: false,
                history: []
            },
            created() {
                // 从localStorage加载历史记录
                const savedHistory = localStorage.getItem('textSimilarityHistory');
                if (savedHistory) {
                    this.history = JSON.parse(savedHistory);
                }
            },
            methods: {
                compareTexts() {
                    if (!this.text1 || !this.text2) {
                        alert('请输入要比较的文本');
                        return;
                    }

                    this.isLoading = true;
                    const config = {
                        headers: {
                            'Content-Type': 'application/x-www-form-urlencoded'
                        }
                    };

                    const params = new URLSearchParams();
                    params.append('text1', this.text1);
                    params.append('text2', this.text2);

                    axios.post(this.baseUrl + '/api/compare', params, config)
                        .then(response => {
                            if (response.data.success) {
                                this.similarity = response.data.similarity;
                                // 添加到历史记录
                                this.addToHistory({
                                    text1: this.text1,
                                    text2: this.text2,
                                    similarity: this.similarity,
                                    time: new Date().toLocaleString()
                                });
                            } else {
                                alert('比较失败：' + response.data.message);
                            }
                        })
                        .catch(error => {
                            if (error.response) {
                                alert('发生错误：' + (error.response.data.message || '未错误'));
                            } else {
                                alert('网络错误，请重试');
                            }
                        })
                        .finally(() => {
                            this.isLoading = false;
                        });
                },
                addToHistory(record) {
                    // 限制历史记录最多保存10条
                    this.history.unshift(record);
                    if (this.history.length > 10) {
                        this.history.pop();
                    }
                    // 保存到localStorage
                    localStorage.setItem('textSimilarityHistory', JSON.stringify(this.history));
                },
                clearHistory() {
                    if (confirm('确定要清除所有历史记录吗？')) {
                        this.history = [];
                        localStorage.removeItem('textSimilarityHistory');
                    }
                },
                deleteHistoryItem(index) {
                    if (confirm('确定要删除这条记录吗？')) {
                        this.history.splice(index, 1);
                        // 更新localStorage
                        if (this.history.length > 0) {
                            localStorage.setItem('textSimilarityHistory', JSON.stringify(this.history));
                        } else {
                            localStorage.removeItem('textSimilarityHistory');
                        }
                    }
                }
            }
        });

        // 修改鼠标移动监听
        document.addEventListener('mousemove', function(e) {
            const bubbles = document.querySelectorAll('.bubble');
            const mouseX = e.clientX;
            const mouseY = e.clientY;

            bubbles.forEach((bubble, index) => {
                const rect = bubble.getBoundingClientRect();
                const bubbleX = rect.left + rect.width / 2;
                const bubbleY = rect.top + rect.height / 2;

                // 计算气泡到鼠标的距离
                const distX = mouseX - bubbleX;
                const distY = mouseY - bubbleY;
                const distance = Math.sqrt(distX * distX + distY * distY);

                // 增加互动距离和效果
                const interactionDistance = 300;  // 增加互动距离
                if (distance < interactionDistance) {
                    const angle = Math.atan2(distY, distX);
                    const force = (interactionDistance - distance) / 5;  // 增加力度
                    const moveX = Math.cos(angle) * force * -1;
                    const moveY = Math.sin(angle) * force * -1;
                    const scale = 1 + force/200;  // 减小缩放比例

                    bubble.style.transform = `translate(${moveX}px, ${moveY}px) scale(${scale})`;
                    bubble.style.zIndex = '0';  // 确保气泡始终在正确的层级
                } else {
                    bubble.style.transform = '';
                }
            });
        });

        // 在创建新气泡的函数中添加随机形状
        function createNewBubble() {
            const newBubble = document.createElement('div');
            newBubble.className = 'bubble';
            
            // 随机大小
            const size = Math.random() * (280 - 160) + 160;
            newBubble.style.width = size + 'px';
            newBubble.style.height = size + 'px';
            
            // 随机位置
            newBubble.style.left = Math.random() * 90 + '%';
            
            // 随机形状
            const shapes = [
                '50%',  // 圆形
                '70% 30% 50% 50% / 30% 70% 30% 70%',  // 极度扭曲的椭圆
                '20% 80% 20% 80% / 80% 20% 80% 20%',  // 极度扭曲的不规则形状
                '80% 20% 60% 40% / 40% 60% 40% 60%',  // 扭曲的水滴
                '90% 10% 70% 30% / 30% 70% 30% 70%',  // 更极端的扭曲
                '25% 75% 25% 75% / 75% 25% 75% 25%',  // 星形变体
                '85% 15% 50% 50% / 50% 50% 15% 85%',  // 不对称扭曲
                '10% 90% 30% 70% / 70% 30% 90% 10%'   // 极端不对称
            ];
            newBubble.style.borderRadius = shapes[Math.floor(Math.random() * shapes.length)];
            
            // 添加点击事件
            newBubble.addEventListener('click', (e) => {
                e.stopPropagation();
                newBubble.classList.add('pop');
                setTimeout(() => {
                    newBubble.remove();
                }, 300);
                
                // 1秒后创建新气泡
                setTimeout(createNewBubble, 1000);
            });
            
            document.querySelector('.bubbles').appendChild(newBubble);
        }

        // 修改原有的气泡点击事件处理
        document.querySelectorAll('.bubble').forEach(bubble => {
            bubble.addEventListener('click', (e) => {
                e.stopPropagation();
                bubble.classList.add('pop');
                setTimeout(() => {
                    bubble.remove();
                }, 300);
                setTimeout(createNewBubble, 1000);
            });
        });
    </script>
</body>
</html> 